//
//  XYVoiceConverter.m
//  TestDemo
//
//  Created by wuxiaoyuan on 2018/9/3.
//  Copyright © 2018年 lange. All rights reserved.
//

#import "XYVoiceConverter.h"
#import "lame.h"
#import "ExtAudioConverter.h"
#import <AVFoundation/AVFoundation.h>
@interface XYVoiceConverter ()

/** 保存的ID值 */
@property (nonatomic, copy) NSString *saveID;
/** 保存拆分后的前后音频路径数组 */
@property (nonatomic, strong) NSMutableArray *copePathArr;
/** 用于确定是否该返回全部拆分完成 */
@property (nonatomic, assign) NSInteger currentIndex;
/** 是否需要转换格式 默认为Yes */
@property (nonatomic, assign) BOOL isNeedChangeToMp3;

@property (nonatomic, copy) NSString *oriName;

@property (nonatomic,assign) NSInteger count;

@end


@implementation XYVoiceConverter


#pragma mark -拆分
- (NSInteger)gotVideoSencendWithPath:(NSString *)path{
    //39.497143
    //17.784000
    AVURLAsset*audioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
    CMTime audioDuration = audioAsset.duration;
    CGFloat audioDurationFloat = CMTimeGetSeconds(audioDuration);
    NSInteger audioDurationSeconds = (ceilf(audioDurationFloat));
    NSLog(@"获取到的音频时长：%ld",audioDurationSeconds);
    return audioDurationSeconds;
}

#pragma mark - 新添加的方法
- (void)xyConvert_audioCropOriginalPath:(NSString *)originalPath insertPath:(NSString *)insertPath insertStartTime:(NSInteger)insertStartTime insertEndTime:(NSInteger)insertEndTime saveID:(NSString *)saveID isNeedMerge:(BOOL)isNeedMerge {
    self.saveID = saveID;
    self.oriName = originalPath;
    //
    NSURL *oriUrl = [NSURL fileURLWithPath:originalPath];
    //原音频总时长
    NSInteger originalAllTime = [self gotVideoSencendWithPath:originalPath];
    //插入的音频总时长
    NSInteger insertAllTime = [self gotVideoSencendWithPath:insertPath];
    //初始化存储数组
    NSMutableArray *cropPathArr = [NSMutableArray array];
    //循环剪切
    _count = 0;
    for (int i = 0; i < 3; i++) {
        NSString *outPutPath = [[self composeDir] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.m4a",self.saveID,i]];
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:outPutPath]) {
            [[NSFileManager defaultManager] removeItemAtPath:outPutPath error:nil];
        }
        NSURL *audioFileOutput = [NSURL fileURLWithPath:outPutPath];
        AVAsset *asset = [AVAsset assetWithURL:oriUrl];
        AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
        CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(0, 1), CMTimeMake(0, 1));
        if (i == 0) {
            [cropPathArr addObject:[NSURL fileURLWithPath:outPutPath]];
            exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(0, 1), CMTimeMake(insertStartTime, 1));
            NSLog(@"0---start = 0,end = %ld",insertStartTime);
        } else if (i == 1){
            //添加插入音频到中间位置用于后面合并
            [cropPathArr addObject:[NSURL fileURLWithPath:insertPath]];
            exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(insertStartTime, 1), CMTimeMake(insertAllTime, 1));
            NSLog(@"1---start = %ld,end = %ld",insertStartTime,insertStartTime+insertAllTime);
        } else if (i == 2){
            [cropPathArr addObject:[NSURL fileURLWithPath:outPutPath]];
            exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(insertEndTime, 1),
                                                        CMTimeMake(originalAllTime, 1));
            NSLog(@"2---start = %ld,end = %ld",insertEndTime,originalAllTime);
        }
        
        exportSession.outputURL = audioFileOutput;
        exportSession.outputFileType = @"com.apple.m4a-audio";//AVFileTypeAppleM4A;
        exportSession.timeRange = exportTimeRange;
      
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            if (AVAssetExportSessionStatusCompleted == exportSession.status) {
                NSLog(@"完成%@",outPutPath);
                _count = _count+1;
                if (_count == 3) {
                    NSLog(@" 拆分全部成功 \n %@", outPutPath);
                    [self cropSuccss];
                    if (isNeedMerge) {
                        [self xyConvert_audioMergeWithMergePathArr:cropPathArr saveID:self.saveID isNeedChangeToMp3:YES];
                    }
                    
                }
                
            } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
                NSLog(@"拆分失败 error: %@", exportSession.error.localizedDescription);
                [self cropFail];
                return;
            }
            
        }];

    }
    
}

#pragma mark - 
- (void)xyConvert_audioCropOriginalPath:(NSString *)originalPath insertPath:(NSString *)insertPath insertTime:(NSInteger)insertTime saveID:(NSString *)saveID isNeedMerge:(BOOL)isNeedMerge{
    
    self.saveID = saveID;
    self.oriName = originalPath;
    //
    NSURL *oriUrl = [NSURL fileURLWithPath:originalPath];
    //原音频总时长
    NSInteger originalAllTime = [self gotVideoSencendWithPath:originalPath];
    //插入的音频总时长
    NSInteger insertAllTime = [self gotVideoSencendWithPath:insertPath];
    //初始化存储数组
    NSMutableArray *cropPathArr = [NSMutableArray array];
    //循环剪切
    for (int i = 0; i < 3; i++) {
        NSString *outPutPath = [[self composeDir] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.m4a",self.saveID,i]];
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:outPutPath]) {
            [[NSFileManager defaultManager] removeItemAtPath:outPutPath error:nil];
        }
        NSURL *audioFileOutput = [NSURL fileURLWithPath:outPutPath];
        AVAsset *asset = [AVAsset assetWithURL:oriUrl];
        AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
        CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(0, 1), CMTimeMake(0, 1));
        if (i == 0) {
            [cropPathArr addObject:[NSURL fileURLWithPath:outPutPath]];
            exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(0, 1), CMTimeMake(insertTime, 1));
            NSLog(@"0---start = 0,end = %ld",insertTime);
        }else if (i == 1){
            //添加插入音频到中间位置用于后面合并
            [cropPathArr addObject:[NSURL fileURLWithPath:insertPath]];
            exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake(insertTime, 1), CMTimeMake(insertAllTime, 1));
            NSLog(@"1---start = %ld,end = %ld",insertTime,insertTime+insertAllTime);
        }else if (i == 2){
            
            if(insertAllTime+insertTime<originalAllTime) {
                [cropPathArr addObject:[NSURL fileURLWithPath:outPutPath]];
                exportTimeRange = CMTimeRangeFromTimeToTime(CMTimeMake((insertAllTime+insertTime), 1),
                                                            CMTimeMake(originalAllTime, 1));
                NSLog(@"2---start = %ld,end = %ld",insertAllTime+insertTime,originalAllTime);
            }
        }
        exportSession.outputURL = audioFileOutput;
        exportSession.outputFileType = AVFileTypeAppleM4A;
        exportSession.timeRange = exportTimeRange;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            if (AVAssetExportSessionStatusCompleted == exportSession.status) {
                NSLog(@"%@",outPutPath);
                if (i == 2) {
                    NSLog(@" 拆分全部成功 \n %@", outPutPath);
                    [self cropSuccss];
                    if (isNeedMerge) {
                        [self xyConvert_audioMergeWithMergePathArr:cropPathArr saveID:self.saveID isNeedChangeToMp3:YES];
                    }
                    
                }
                
                
            } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
                NSLog(@"拆分失败 error: %@", exportSession.error.localizedDescription);
                [self cropFail];
                return;
            }
            
        }];
    }

}


#pragma mark -合并
- (void)xyConvert_audioMergeWithMergePathArr:(NSMutableArray *)mergePathArr saveID:(NSString *)saveID isNeedChangeToMp3:(BOOL)isNeedChangeToMp3{

    self.isNeedChangeToMp3 = isNeedChangeToMp3;
    self.saveID = saveID;
    //目标地址
    NSString *destPath = [[self composeDir] stringByAppendingString:[NSString stringWithFormat:@"%@.m4a",saveID]];
    if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
        [[NSFileManager defaultManager] removeItemAtPath:destPath error:nil];
    }

    AVMutableComposition *mixComposition = [AVMutableComposition composition];
    // 开始时间
    CMTime beginTime = kCMTimeZero;
    // 设置音频合并音轨
    AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSError *error = nil;
    for (NSURL *sourceURL in mergePathArr) {
        //音频文件资源
        AVURLAsset *audioAsset = [[AVURLAsset alloc] initWithURL:sourceURL options:nil];
        //需要合并的音频文件的区间
        CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
        // ofTrack 音频文件内容
        BOOL success = [compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject] atTime:beginTime error:&error];
        if (!success) {
            NSLog(@"Error: %@",error);
            [self mergeFailWithType:1];
            return;
        }
        beginTime = CMTimeAdd(beginTime, audioAsset.duration);
        
    }
    // presetName 与 outputFileType 要对应 导出合并的音频
    AVAssetExportSession* assetExportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetAppleM4A];
    assetExportSession.outputURL = [NSURL fileURLWithPath:destPath];
    assetExportSession.outputFileType = AVFileTypeAppleM4A;
    assetExportSession.shouldOptimizeForNetworkUse = YES;
    [assetExportSession exportAsynchronouslyWithCompletionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (assetExportSession.status == AVAssetExportSessionStatusCompleted) {
                NSLog(@"合并成功----");
                if (isNeedChangeToMp3) {
                    NSLog(@"需要转换音频格式");
                    for (int i = 0; i<3; i++) {
                        NSString *tempPath = [[self composeDir] stringByAppendingString:[NSString stringWithFormat:@"%@%d.m4a",saveID,i]];
                        if ([[NSFileManager defaultManager] fileExistsAtPath:tempPath]) {
                            [[NSFileManager defaultManager] removeItemAtPath:tempPath error:nil];
                        }
                    }
                    
                    [self changeToMp3];
                    
                }else{
                    [self mergeSuccssWithType:1];
                }
            } else {
                // 其他情况, 具体请看这里`AVAssetExportSessionStatus`.
                NSLog(@"合并失败：%@",assetExportSession.error);
                [self mergeFailWithType:1];
            }
            
        });
        
    }];
    
}
- (void)changeToMp3{
    //开始转换m4a格式为wav
    NSString *destPath = [[self composeDir] stringByAppendingString:[NSString stringWithFormat:@"%@.m4a",self.saveID]];;
   // NSString *destPath2 = [[self composeDir] stringByAppendingString:[NSString stringWithFormat:@"Wav%@.wav",self.saveID]];;
    NSString *destPath2 = self.oriName;
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:destPath2]) {
        [[NSFileManager defaultManager] removeItemAtPath:destPath2 error:nil];
    }
    ExtAudioConverter* converter = [[ExtAudioConverter alloc] init];
    converter.outputSampleRate = 16000;//采样率
    converter.outputNumberChannels = 1;//声道数
    converter.outputFileType = kAudioFileWAVEType;//设置文件格式
    converter.outputFormatID = kAudioFormatLinearPCM;
    
    converter.inputFile =  destPath;
    converter.outputFile = destPath2;
    BOOL isChangeSuccss =  [converter convert];
    if (isChangeSuccss) {
        NSLog(@"转换成功");
        if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
            [[NSFileManager defaultManager] removeItemAtPath:destPath error:nil];
        }
        [self mergeSuccssWithType:2];
    }else{
        NSLog(@"转换失败");
        [self mergeFailWithType:2];
    }
}

#pragma mark -Methory
- (NSString *)composeDir {
    NSString *doucDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *compseDir = [NSString stringWithFormat:@"%@/AudioCompose/", doucDir];
    BOOL isDir = NO;
    BOOL existed = [fileManager fileExistsAtPath:compseDir isDirectory:&isDir];
    if ( !(isDir == YES && existed == YES) ) {
        [fileManager createDirectoryAtPath:compseDir withIntermediateDirectories:YES attributes:nil error:nil];
        
    }
    return compseDir;
}


- (void)cropSuccss{
    if ([self.delegate respondsToSelector:@selector(convertDelegete_cropSuccss)]) {
        [self.delegate convertDelegete_cropSuccss];
    }
}
- (void)cropFail{
    if ([self.delegate respondsToSelector:@selector(convertDelegete_cropFail)]) {
        [self.delegate convertDelegete_cropFail];
    }
}


- (void)mergeSuccssWithType:(NSInteger)typeInt{
    if (typeInt == 1) {
        NSLog(@"合并成功类型1--");
    }else{
        NSLog(@"合并后转换音频成功--");
    }
    if ([self.delegate respondsToSelector:@selector(convertDelegete_mergeSuccss)]) {
        [self.delegate convertDelegete_mergeSuccss];
    }
}
- (void)mergeFailWithType:(NSInteger)typeInt{
    if (typeInt == 1) {
        NSLog(@"合并失败--");
    }else{
        NSLog(@"合并后转换音频失败--");
    }
    if ([self.delegate respondsToSelector:@selector(convertDelegete_mergeFail)]) {
        [self.delegate convertDelegete_mergeFail];
    }
}

#pragma mark -lazy
- (NSMutableArray *)copePathArr{
    if (!_copePathArr) {
        _copePathArr = [NSMutableArray array];
    }
    return _copePathArr;
}


@end
